﻿#include "cdatabaseopermgr.h"

#include "cdatabaseopermgr_private.h"
//#include "publicdefine.h"

#define MODULE_TYPE_DATABASE 0

const int JUDGE_IS_OPEN_TIME = 3000;                           //周期判断连接状态时间，单位ms

//中文显示乱码问题
#define DB_A2T QString

/***********************************************
* [className]   CDatabaseOperMgr
* [func]        数据库管理类
* [author]      jhb
* [date]        2023-12-06 09:13
* [Modification Log]
* Version               By              Notes
* v0.0.1                jhb             初次建立
************************************************/
CDatabaseOperMgr::CDatabaseOperMgr()
{
    d_ptr = new CDatabaseOperMgrPrivate;
    d_ptr->q_ptr = this;

    connect(this, &CDatabaseOperMgr::sigOpenDone, this, &CDatabaseOperMgr::sigDbOpenDone);
}

CDatabaseOperMgr::~CDatabaseOperMgr()
{
    d_ptr->close();
    //SAFE_DELETE(d_ptr)
    if(nullptr != d_ptr)
    {
        delete d_ptr;
        d_ptr = nullptr;
    }
}

//设置数据库读写连接数量
bool CDatabaseOperMgr::setConnectNumber(const quint8 &nReadNum, const quint8 &nWriteNum)
{
    return d_ptr->setConnectNumber(nReadNum, nWriteNum);
}

//设置数据库连接信息
bool CDatabaseOperMgr::setDbConfigInfo(const CDataBaseConfig &stDbCfg)
{
    return d_ptr->setDbConfigInfo(stDbCfg);
}

//设置数据库连接信息
bool CDatabaseOperMgr::setDbConfigInfo(const CDataBaseConfig &stDbCfg, QVector<QString> vecTableName)
{
    return d_ptr->setDbConfigInfo(stDbCfg, vecTableName);
}

//设置数据库连接信息
bool CDatabaseOperMgr::setDbConfigInfo(const CDataBaseConfig &stDbCfg, const QString &strTables)
{
    QStringList strList = strTables.split(",");
    return d_ptr->setDbConfigInfo(stDbCfg, strList);
}

//设置数据库连接信息
bool CDatabaseOperMgr::setDbConfigInfo(const CDataBaseConfig &stDbCfg, QVector<CDbTableInfo> vecTableInfo)
{
    return d_ptr->setDbConfigInfo(stDbCfg, vecTableInfo);
}

//开启事务
bool CDatabaseOperMgr::transaction(const QString &strId, int nType)
{
    if(false == d_ptr->m_bIsOpen) return false;
    return d_ptr->transaction(strId, nType);
}

//提交事务
bool CDatabaseOperMgr::commit(const QString &strId)
{
    if(false == d_ptr->m_bIsOpen) return false;
    return d_ptr->commit(strId);
}

//回滚事务
bool CDatabaseOperMgr::rollback(const QString &strId)
{
    if(false == d_ptr->m_bIsOpen) return false;
    return d_ptr->rollback(strId);
}

//获取数据库操作信息
CDbTableDataInfo *CDatabaseOperMgr::getDbDataInfo(const int &nTable, const int &nLock)
{
    if(false == d_ptr->m_bIsOpen) return nullptr;
    return d_ptr->getDbDataInfo(nTable, nLock);
}

//获取数据库操作信息
CDbTableDataInfo *CDatabaseOperMgr::getDbDataInfo(const QString &strTable, const int &nLock)
{
    if(false == d_ptr->m_bIsOpen) return nullptr;
    return d_ptr->getDbDataInfo(strTable, nLock);
}

//获取执行结果
bool CDatabaseOperMgr::getResult(const int &nTable, const int &nLock)
{
    if(false == d_ptr->m_bIsOpen) return false;
    return d_ptr->getResult(nTable, nLock);
}

//获取执行结果
bool CDatabaseOperMgr::getResult(const QString &strTable, const int &nLock)
{
    if(false == d_ptr->m_bIsOpen) return false;
    return d_ptr->getResult(strTable, nLock);
}

//设置日志组件指针
void CDatabaseOperMgr::setLogPtr(CLogBase *pLog)
{
    d_ptr->m_pLog = pLog;
}

//设置数据库打开成功回调函数
bool CDatabaseOperMgr::setDbOpenDoneCb(DbOpenDoneCallback func)
{
    d_ptr->m_pDbOpenDoneCb = func;
    return true;
}

//使用结构体数据直接执行SQL
bool CDatabaseOperMgr::exec(CDatabaseExecData &data, const int &nLock)
{
    if(false == d_ptr->m_bIsOpen) return false;
    CDbTableDataInfo *pInfo = getDbDataInfo(data.sTableName);
    if(nullptr == pInfo)
    {
        data.sErr = QObject::tr("Table occupied, sql executing failed");
        return false;
    }
    //SQL操作类型
    pInfo->setWorkType(enSQLCUSTOM);
    //问号占位符处理
    if((false == data.vecField.isEmpty())
            && (false == data.vecValue.isEmpty()))
    {
        pInfo->addResultField(data.vecField);
        pInfo->addResultValue(data.vecValue);
    }
    //添加SQL
    pInfo->addSql(data.sSql);
    //执行SQL
    bool bRet = getResult(data.sTableName, enLockALWAYS);
    //执行失败，手动释放资源锁
    if(false == bRet)
    {
        data.sErr = pInfo->getLastError();
        if(enNONBLOCK == nLock) pInfo->unlock();
        return bRet;
    }
    //查询语句特殊处理
    if(enSQLSELECT == pInfo->getSqlType())
    {
        //获取数据
        data.vecRecord = pInfo->getReRecord();
    }
    //手动释放资源锁
    if(enNONBLOCK == nLock) pInfo->unlock();
    return bRet;
}

//工作线程
void CDatabaseOperMgr::slotWorkProc()
{
    bool bStartFlag = false;
    while (false == m_bStopWorkThread)
    {
        bStartFlag = true;
        if(false == d_ptr->m_bIsOpen)
        {
            bool bDBOpen = d_ptr->open();
            if(bDBOpen)
            {
                //通知数据库打开成功
                if (d_ptr->m_pDbOpenDoneCb) (d_ptr->m_pDbOpenDoneCb)();
                emit sigOpenDone();
            }

            if(false == d_ptr->m_bIsOpen)
            {
                threadSleep(5000);
                continue;
            }
        }
        else
        {
            //判断数据库连接状态,并在内部自动重连
            d_ptr->isOpen();
        }
        threadSleep(JUDGE_IS_OPEN_TIME);
    }
    //启动后被停止，需要清理数据
    if(bStartFlag)
    {
        d_ptr->close();
    }
}
